<template>
  <div>
    <el-button @click="batchDetele" type="danger" round>批量删除</el-button>
    <!--树形控件 https://element.eleme.cn/#/zh-CN/component/tree -->
    <el-tree 
      :data="menus" 
      :props="defaultProps" 
      :expand-on-click-node="false" 
      show-checkbox node-key="catId" 
      draggable
      :allow-drop="allowDrop"
      @node-drop="handleDrop"
      ref="MenusTree"
      :default-expanded-keys="expandedKeys">
      <span class="custom-tree-node" slot-scope="{ node, data }">
        <span>{{ node.label }}</span>
        <span>
          <el-button v-if="node.level <= 2" type="text" size="mini" @click="append(data)">
            新增
          </el-button>
          <el-button v-if="node.childNodes.length == 0" type="text" size="mini" @click="remove(node, data)">
            删除
          </el-button>
          <el-button type="text" size="mini" @click="update(node, data)">
            修改
          </el-button>
        </span>
      </span>
    </el-tree>

    <!--Dialog对话框 https://element.eleme.cn/#/zh-CN/component/dialog-->
    <el-dialog title="新增分类" :visible.sync="appendDialogVisible">
      <el-form :model="category">
        <el-form-item label="分类名称">
          <el-input v-model="category.name" autocomplete="off"></el-input>
        </el-form-item>
      </el-form>
      <div slot="footer" class="dialog-footer">
        <el-button @click="cancelAppendDialog">取 消</el-button>
        <el-button type="primary" @click="confirmAppendDialog">确 定</el-button>
      </div>
    </el-dialog>

    <el-dialog title="修改分类" :visible.sync="updateDialogVisible">
      <el-form :model="updateCategory">
        <el-form-item label="分类名称">
          <el-input v-model="updateCategory.name" autocomplete="off"></el-input>
        </el-form-item>
        <el-form-item label="图标">
          <el-input v-model="updateCategory.icon" autocomplete="off"></el-input>
        </el-form-item>
        <el-form-item label="计量单位">
          <el-input v-model="updateCategory.productUnit" autocomplete="off"></el-input>
        </el-form-item>
      </el-form>
      <div slot="footer" class="dialog-footer">
        <el-button @click="cancelUpdateDialog">取 消</el-button>
        <el-button type="primary" @click="confirmUpdateDialog">确 定</el-button>
      </div>
    </el-dialog>

  </div>
</template>

<script>
//这里可以导入其他文件（比如：组件，工具 js，第三方插件 js，json文件，图片文件等等）
//例如：import 《组件名称》 from '《组件路径》';

export default {
    data() {
      return {
        menus: [],
        expandedKeys:[],
        defaultProps: {
          children: 'children',
          label: 'name'
        },
        appendDialogVisible:false,
        category: {name:"",parentCid:0,catLevel:0,showStatus:1,sort:0},
        updateDialogVisible:false,
        updateCategory: {catId:"",parentCid:0,name:"",icon:"",productUnit:""},
      };
    },
    methods: {

      // 获取分类数据列表
      getCategoryList () {
        this.$http({
          url: this.$http.adornUrl('/product/category/listWithTree'),
          method: 'get',
        }).then(responseData=>{
            console.log("成功获取分类数据列表",responseData)
            this.menus = responseData.data.data;
        })
      },

      append(data) {
        console.log("append",data)
        this.appendDialogVisible=true;
        this.category.parentCid = data.catId;
        this.category.catLevel= data.catLevel*1 + 1;
      },

      remove(node, data) {
        console.log(node)
        console.log(data)

        this.$confirm('是否确定删除菜单项: [ '+data.name+' ] ?', '提示', {
          confirmButtonText: '确定',
          cancelButtonText: '取消',
          type: 'warning'
        }).then(() => {
          
          let ids = [data.catId];
          this.$http({
            url: this.$http.adornUrl('/product/category/delete'),
            method: 'post',
            data: this.$http.adornData(ids, false)
          }).then((responseData) => {
            console.log("删除成功~")
            this.$message({
              type: 'success',
              message: '删除成功!'
            });

            //刷新菜单列表
            this.expandedKeys = [ node.parent.data.catId ]
            this.getCategoryList();

          })

        }).catch(() => {
          this.$message({
            type: 'info',
            message: '已取消删除'
          });          
        });



      },
      cancelAppendDialog(){
        this.appendDialogVisible=false;
        this.category = {name:"",parentCid:0,catLevel:0,showStatus:1,sort:0};
      },
      confirmAppendDialog(){

        //分类名不能为空
        this.category.name = this.category.name.trim();
        if(this.category.name.length < 1){
          this.$message({
            type: 'error',
            message: '分类名称不能为空!'
          });

          return;
        }

        //执行添加
        console.log("即将添加",this.category)
        this.$http({
          url: this.$http.adornUrl('/product/category/save'),
            method: 'post',
            data: this.$http.adornData(this.category, false)
          }).then((responseData) => {
            this.$message({
              type: 'success',
              message: '新增分类成功!'
            });

            //刷新菜单列表
            this.expandedKeys = [ this.category.parentCid ];
            this.getCategoryList();

            //关闭对话框
            this.cancelAppendDialog();
          })

      }
      ,
      update(node,data){
        console.log(node)
        console.log(data)

        this.$http({
          url: this.$http.adornUrl('/product/category/info/'+data.catId),
          method: 'get',
          params: this.$http.adornParams({})
        }).then((responseData) => {
          console.log(responseData)
          let freshCategory = responseData.data.category;
          this.updateCategory.catId = freshCategory.catId;
          this.updateCategory.parentCid = freshCategory.parentCid;
          this.updateCategory.name = freshCategory.name;
          this.updateCategory.icon = freshCategory.icon;
          this.updateCategory.productUnit = freshCategory.productUnit;

          this.updateDialogVisible = true;
        })
      }
      ,
      cancelUpdateDialog(){
        this.updateDialogVisible=false;
        this.updateCategory = {catId:"",name:"",icon:"",productUnit:""};
      }
      ,
      confirmUpdateDialog(){

        //分类名不能为空
        this.updateCategory.name = this.updateCategory.name.trim();
        if(this.updateCategory.name.length < 1){
          this.$message({
            type: 'error',
            message: '分类名称不能为空!'
          });

          return;
        }

        //执行修改
        console.log("即将修改",this.updateCategory)
        this.$http({
          url: this.$http.adornUrl('/product/category/update'),
            method: 'post',
            data: this.$http.adornData(this.updateCategory, false)
          }).then((responseData) => {
            this.$message({
              type: 'success',
              message: '修改分类成功!'
            });

            //刷新菜单列表
            this.expandedKeys = [ this.updateCategory.parentCid ];
            this.getCategoryList();

            //关闭对话框
            this.cancelUpdateDialog();
          })

      }
      ,
      //被拖拽的draggingNode 放在 参考系dropNode 的 type位置 
      //type 参数有三种情况：'prev'、'inner' 和 'next'，分别表示放置在目标节点前、插入至目标节点和放置在目标节点后
      allowDrop(draggingNode, dropNode, type){
        //这个输出会被高频调用,此时控制台的输出并不是严格的先后,所以控制台上的最后一次输出并不代表最终放置的位置
        //console.log("draggingNode",draggingNode,"dropNode",dropNode,type)
        var flag = true;

        //要求菜单层级最多三级
        var parentNode = type=='inner' ? dropNode : dropNode.parent;
        if( this.countParnetNodeGrade(parentNode) + this.countDraggingNodeMaxDeep(draggingNode) > 3 ){
          flag = false;
        }

        //console.log(draggingNode.label+" 想放到 "+dropNode.label+" "+type+" "+flag)
        return flag;
      }
      ,
      //计算父节点是几级菜单  一直向上找parent,为null则表示当前是根节点
      countParnetNodeGrade(parentNode){
        var parentNodeGrade=0;  //0级代表root根节点
        while(parentNode.parent != null){
          parentNodeGrade+=1;
          parentNode = parentNode.parent;
        }
        
        return parentNodeGrade;
      }
      ,
      //计算被拖动的节点最大深度
      countDraggingNodeMaxDeep(draggingNode){
        var selfDeep = 1; //节点自身至少为1
        var childMaxDeep = 0; //默认没有子节点
        if(draggingNode.childNodes.length>0){
          //如果有子节点,则继续计算所有子节点中的最大深度
          for (var i=0;i<draggingNode.childNodes.length;i++) {
            var currentNodeMaxDeep = this.countDraggingNodeMaxDeep(draggingNode.childNodes[i]);
            childMaxDeep = currentNodeMaxDeep > childMaxDeep ? currentNodeMaxDeep : childMaxDeep;
          }
        }

        return selfDeep+childMaxDeep;
      }
      ,
      handleDrop(draggingNode, dropNode, dropType, ev) {
        console.log(draggingNode.label+' 已经放在了 '+dropNode.label+" 的 "+dropType);
        console.log(draggingNode ,' 已经放在了 ',dropNode ," 的 ",dropType);
        

        let parentNode = dropType=='inner' ? dropNode : dropNode.parent;
        let parentCid = parentNode.parent == null ? 0 : parentNode.data.catId;
        console.log("parentNode",parentNode," parentCid ",parentCid)

        //只需要告诉后端 draggingNode 的parentCid发生了改变,那其它的都可以直接在后台计算
        //这里就省略对其他字段的维护,直接用原有update更新下其parentCid
        this.$http({
          url: this.$http.adornUrl('/product/category/update'),
          method: 'post',
          data: this.$http.adornData({catId:draggingNode.data.catId, parentCid:parentCid}, false)
        }).then((responseData) => {

            this.$message({
              type: 'success',
              message: '移动分类成功!'
            });

            //刷新菜单列表
            this.expandedKeys = [ parentCid ];
            this.getCategoryList();
        })

      }
      ,
      batchDetele(){

        let checkedItems = this.$refs.MenusTree.getCheckedNodes(); //这里返回的是实际数据数组,而不是被包装的Node元素
        console.log(checkedItems)
        if(checkedItems.length<1){
          this.$message({
              type: 'error',
              message: '至少选中一个要删除的菜单项'
            });
          return;
        }

        let ids = []
        for(var i=0;i<checkedItems.length;i++){
          ids.push(checkedItems[i].catId);
        }
        console.log(ids)


        this.$confirm('是否确定批量删除菜单项 ?', '提示', {
          confirmButtonText: '确定',
          cancelButtonText: '取消',
          type: 'warning'
        }).then(() => {

          this.$http({
            url: this.$http.adornUrl('/product/category/delete'),
            method: 'post',
            data: this.$http.adornData(ids, false)
          }).then((responseData) => {
            console.log("批量删除成功~")
            this.$message({
              type: 'success',
              message: '批量删除成功!'
            });

            //刷新菜单列表
            this.expandedKeys=[];
            this.getCategoryList();

          })

        }).catch(() => {
          this.$message({
            type: 'success',
            message: '已取消批量删除'
          });          
        });

      }


    },
    created(){
        this.getCategoryList();
    }
  };
</script>
<style lang='scss' scoped>
//@import url(); 引入公共 css 类
</style>